package org.brisling.workflow.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.task.Task;
import org.brisling.base.domain.inf.BaseFlowDomainInf;
import org.brisling.common.util.JsonUtil;
import org.brisling.common.util.ReflectDataUtil;
import org.brisling.workflow.domain.FlowTaskConfig;

public class NodeUtil {
	
	
	private static NodeUtil nu;
	
	private NodeUtil(){};
	
	public static NodeUtil getInstance(){
		if(nu==null){
			nu = new NodeUtil();
		}
		return nu;
	}

	/**
	 * 获取流程上一节点
	 * @param flowid	流程定义id
	 * @param task		流程任务实例
	 * @param repositoryService	流程定义实例仓库
	 * @param historyService	流程执行历史服务类
	 * @return
	 */
  	public static  List<ActivityImpl> getIncommingNode(String flowid,Task task,RepositoryService repositoryService,HistoryService historyService){
  		getInstance();
  		String procid = task.getProcessInstanceId();
  		String _key = task.getTaskDefinitionKey();
		return getIncommingNode(flowid,procid,_key,repositoryService,historyService);
  	}
  	
  	
  	/**
	 * 获取流程上一节点
	 * @param flowid	流程定义id
	 * @param task		流程任务实例
	 * @param repositoryService	流程定义实例仓库
	 * @param historyService	流程执行历史服务类
	 * @return
	 */
  	public static  List<ActivityImpl> getIncommingNode(String flowid,String procId,String taskKey,RepositoryService repositoryService,HistoryService historyService){
  		getInstance();
  		ProcessDefinitionEntity pdImpl = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(flowid);
   		
  		
  		//获取执行记录
  		 List<HistoricTaskInstance> list = historyService//与历史数据（历史表）相关的Service  
                    .createHistoricTaskInstanceQuery()//创建历史任务实例查询  
                    .processInstanceId(procId)//  
                    .orderByExecutionId().asc()  
                    .list();  
  		
		//获取当前节点定义
		String _key =taskKey;
		
		ActivityImpl curAct = pdImpl.findActivity(_key);
		
		//取得前一节点
		List<PvmTransition> inActs = curAct.getIncomingTransitions();
		
		List<String> incomingNode = new ArrayList<String>();
		
		incomingNode = recursionList(inActs,incomingNode);
		//跳转节点定义
		List<ActivityImpl> toActs = new ArrayList<ActivityImpl>();    		
		
		if(list!=null && incomingNode!=null){
			int cnt = 0;
			String oldAct = null;
			for(HistoricTaskInstance h:list){
				//迭代执行记录
				for(String p:incomingNode){
					//迭代入口节点
					if(h.getTaskDefinitionKey().compareTo(p)==0){
						oldAct  = h.getTaskDefinitionKey();
						toActs.add(pdImpl.findActivity(oldAct));
						cnt ++;
					}
				}    				
			}
		}
		return toActs;
  	}
  	
  	private static List<String> recursionList(List<PvmTransition> pvms,List<String> nodes){
  		
  		
  		for(PvmTransition p:pvms){
  			nodes = recursionNode(p.getSource(),nodes);
  		}
  		return nodes;
  	}
  	
  	private static List<String> recursionNode(PvmActivity p,List<String> nodes){
  		
  			String _type = (String) p.getProperty("type");
  			if(_type!=null){
  				switch(_type){
  				case "userTask":
  					nodes.add(p.getId());
  				case "startevent":
  					return nodes;
  					
  				default:
  					return recursionList(p.getIncomingTransitions(),nodes);
  					
  				}	  				
  			}
  			return recursionList(p.getIncomingTransitions(),nodes);
  			
  		
  	}
  	
  	/**
  	 * 
  	 * @return
  	 */
  	public static Map<String,Object> getNodeVariable(BaseFlowDomainInf bf,FlowTaskConfig ftc){
  		
  		String _mapkey = "variableFilter";
  		Map<String,Object> retMap = new HashMap<String,Object>();
		Map<String,Map<String,String>> _ac = null;
		//获取流程节点配置
		if(ftc!=null && ftc.getActivityConfig()!=null)
			_ac =JsonUtil.bodyToObj(ftc.getActivityConfig(), HashMap.class);
		
		//获取流程变量配置
		if(_ac!=null && _ac.containsKey(_mapkey)){
			Object obj = _ac.get(_mapkey);
			String[] fnames = null;
			if(obj!=null){
				//判断流程变量是否有效
				fnames = obj.toString().trim().split(",");
				if(fnames.length>0){
					for(String f:fnames){
						//迭代反射获取变量配置
						retMap.put(f, ReflectDataUtil.getFieldValue(f, bf));
					}
				}
			}			
		}
		return retMap;
  	}
}
